﻿//==============================================================================
// Vector2 
//==============================================================================

//-------------------------------------------------------------------------
//
//-------------------------------------------------------------------------
#include "stdafx.h"
#include "Math.h"
#include "Matrix.h"
#include "Vector2.h"

//-------------------------------------------------------------------------
//
//-------------------------------------------------------------------------
namespace LNote
{
namespace Core
{
namespace Math
{

//==============================================================================
// ■ Vector2 クラス
//==============================================================================

    const Vector2   Vector2::ZERO( 0, 0 );
    const Vector2   Vector2::UNIT_X( 1, 0 );
    const Vector2   Vector2::UNIT_Y( 0, 1 );
    const Vector2   Vector2::UNIT_SCALE( 1, 1 );

	//----------------------------------------------------------------------
	// ● 指定された行列を使って座標変換する
	//----------------------------------------------------------------------
    void Vector2::transform( const Matrix& matrix_ )
	{
		// ( x, y, z, 1 ) として計算する
		lnFloat tx = x;
		lnFloat ty = y;
        lnFloat w = 1.0f / ( tx * matrix_.m03 + ty * matrix_.m13 + matrix_.m33 );
		x = ( tx * matrix_.m00 + ty * matrix_.m10 + matrix_.m30 ) * w;
		y = ( tx * matrix_.m01 + ty * matrix_.m11 + matrix_.m31 ) * w;
	}

	//--------------------------------------------------------------------------
	// ▼ static

	//----------------------------------------------------------------------
	// ● 2D ベクトルの正規化したベクトルを返す
	//----------------------------------------------------------------------
    void Vector2::normalize( Vector2* out_, const Vector2& vec_ )
    {
        lnFloat t = vec_.x * vec_.x + vec_.y * vec_.y;
        t = 1.f / Asm::sqrt( t );
		out_->x = vec_.x * t;
		out_->y = vec_.y * t;
    }

	void Vector2::normalize( Vector2* out_, const Vector2& vec_, const Vector2& def_vec_ )
    {
        lnFloat t = vec_.x * vec_.x + vec_.y * vec_.y;
        if ( t == 0 )
        {
            *out_ = def_vec_;
            return;
        }
        t = 1.f / Asm::sqrt( t );
		out_->x = vec_.x * t;
		out_->y = vec_.y * t;
    }

	//----------------------------------------------------------------------
	// ● 2 つの 2D ベクトルの内積を計算する
	//----------------------------------------------------------------------
	lnFloat Vector2::dot( const Vector2& vec1_, const Vector2& vec2_ )
    {
        return ( vec1_.x * vec2_.x ) + ( vec1_.y * vec2_.y );
    }

	//----------------------------------------------------------------------
	// ● 2 つの 2D ベクトルの外積を計算し、z 要素を返す
	//----------------------------------------------------------------------
	lnFloat Vector2::crossZ( const Vector2& vec1_, const Vector2& vec2_ )
    {
        return ( vec1_.x * vec2_.y ) - ( vec1_.y * vec2_.x );
    }


//-------------------------------------------------------------------------
//
//-------------------------------------------------------------------------

} // namespace Math
} // namespace Core
} // namespace LNote

//==============================================================================
//
//==============================================================================